package org.linlinjava.litemall.wx.web;

import com.github.pagehelper.PageHelper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import jdk.nashorn.internal.ir.CallNode;
import lombok.RequiredArgsConstructor;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.checkerframework.checker.units.qual.C;
import org.linlinjava.litemall.core.system.SystemConfig;
import org.linlinjava.litemall.core.util.ResponseUtil;
import org.linlinjava.litemall.db.domain.LitemallCategory;
import org.linlinjava.litemall.db.domain.LitemallGoods;
import org.linlinjava.litemall.db.domain.LitemallSeckill;
import org.linlinjava.litemall.db.service.*;
import org.linlinjava.litemall.wx.annotation.LoginUser;
import org.linlinjava.litemall.wx.service.HomeCacheManager;
import org.linlinjava.litemall.wx.service.WxGrouponRuleService;
import org.linlinjava.litemall.wx.util.CloneUtil;
import org.linlinjava.litemall.wx.vo.SecKillInfoVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;

/**
 * 首页服务
 */
@RestController
@RequestMapping("/wx/home")
@Validated
@Api("首页数据")
@RequiredArgsConstructor(onConstructor = @_(@Autowired))
public class WxHomeController {
    private final Log logger = LogFactory.getLog(WxHomeController.class);

    private final BannerService bannerService;

    private final GoodsService goodsService;

    private final CategoryService categoryService;

    private final static ArrayBlockingQueue<Runnable> WORK_QUEUE = new ArrayBlockingQueue<>(9);

    private final static RejectedExecutionHandler HANDLER = new ThreadPoolExecutor.CallerRunsPolicy();

    private static ThreadPoolExecutor executorService = new ThreadPoolExecutor(9, 9, 1000, TimeUnit.MILLISECONDS, WORK_QUEUE, HANDLER);

    @GetMapping("/cache")
    @ApiOperation("缓存清除")
    public Object cache(@NotNull String key) {
        if (!key.equals("litemall_cache")) {
            return ResponseUtil.fail();
        }

        // 清除缓存
        HomeCacheManager.clearAll();
        return ResponseUtil.ok("缓存已清除");
    }

    /**
     * 首页数据
     * @param userId 当用户已经登录时，非空。为登录状态为null
     * @return 首页数据
     */
    @GetMapping("/index")
    @ApiOperation("首页数据")
    public Object index(@LoginUser Integer userId) {
        //优先从缓存中读取
        if (HomeCacheManager.hasData(HomeCacheManager.INDEX)) {
            return ResponseUtil.ok(HomeCacheManager.getCacheData(HomeCacheManager.INDEX));
        }
        // 滚动图片
        Callable<List> bannerListCallable = bannerService::queryIndex;
        // 分类
        Callable<List> channelListCallable = categoryService::queryChannel;
        // 今日秒杀
        Callable<List> killListCallable = goodsService::secKillNew;
        // 底部商品展示（多分类）
        List<Map> categoryList = getCategoryList();

        FutureTask<List> bannerTask = new FutureTask<>(bannerListCallable);
        FutureTask<List> channelTask = new FutureTask<>(channelListCallable);
        FutureTask<List> killTask = new FutureTask<>(killListCallable);

        executorService.submit(bannerTask);
        executorService.submit(channelTask);
        executorService.submit(killTask);

        Map<String, Object> entity = new HashMap<>();
        try {
            entity.put("banner", bannerTask.get());
            entity.put("channel", channelTask.get());
            List<LitemallGoods> list = killTask.get();
            List<SecKillInfoVo> secKillInfoVos = CloneUtil.cloneList(list, SecKillInfoVo.class);
            entity.put("kill", secKillInfoVos);
            entity.put("floorGoodsList", categoryList);
            //缓存数据
            HomeCacheManager.loadData(HomeCacheManager.INDEX, entity);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        return ResponseUtil.ok(entity);
    }

    private List<Map> getCategoryList() {
        List<Map> categoryList = new ArrayList<>();
        List<LitemallCategory> catL1List = categoryService.queryL1WithoutRecommend(0, SystemConfig.getCatlogListLimit());
        // 今日推荐商品
        LitemallCategory recommendCategory = new LitemallCategory();
        recommendCategory.setName("推荐");
        recommendCategory.setId(1);
        catL1List.add(recommendCategory);
        for (LitemallCategory catL1 : catL1List) {
//            List<LitemallCategory> catL2List = categoryService.queryByPid(catL1.getId());
//            List<Integer> l2List = new ArrayList<>();
//            for (LitemallCategory catL2 : catL2List) {
//                l2List.add(catL2.getId());
//            }
//            List<LitemallGoods> categoryGoods;
//            if (l2List.size() == 0) {
//                categoryGoods = new ArrayList<>();
//            } else {
//                categoryGoods = goodsService.queryByCategory(l2List, page, limit);
//            }
//            if (1 == recommendCategory.getId()) {
//                categoryGoods = goodsService.queryByNew(page, limit);
//            }

            Map<String, Object> catGoods = new HashMap<>();
            catGoods.put("id", catL1.getId());
            catGoods.put("name", catL1.getName());
            catGoods.put("desc", catL1.getDesc());
//            catGoods.put("goodsList", categoryGoods);
            categoryList.add(catGoods);
        }
        return categoryList;
    }

    /**
     * 商城介绍信息
     * @return 商城介绍信息
     */
    @GetMapping("/about")
    @ApiOperation("首页数据")
    public Object about() {
        Map<String, Object> about = new HashMap<>();
        about.put("name", SystemConfig.getMallName());
        about.put("address", SystemConfig.getMallAddress());
        about.put("phone", SystemConfig.getMallPhone());
        about.put("qq", SystemConfig.getMallQQ());
        about.put("longitude", SystemConfig.getMallLongitude());
        about.put("latitude", SystemConfig.getMallLatitude());
        return ResponseUtil.ok(about);
    }
}